package com.yc.cloud.admin.service.impl;

import com.yc.cloud.admin.dto.SnapshotConfig;
import com.yc.cloud.admin.service.SnapshotStrategyResolver;
import com.yc.cloud.entity.*;
import com.yc.cloud.mapper.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;

/**
 * 抓图策略解析服务实现
 * 
 * @author kinggu
 * @since 2025-10-10
 */
@Slf4j
@Service
public class SnapshotStrategyResolverImpl implements SnapshotStrategyResolver {
    
    @Resource
    private HwCameraSnapshotStrategyMapper snapshotStrategyMapper;
    
    @Resource
    private HwCameraSnapshotRelationMapper snapshotRelationMapper;
    
    @Resource
    private HwCameraSnapshotRecordMapper snapshotRecordMapper;
    
    @Override
    public HwCameraSnapshotStrategy getEffectiveStrategy(Long cameraId) {
        log.debug("获取摄像头[{}]的有效抓图策略", cameraId);
        
        // 1. 查找摄像头的专属策略
        HwCameraSnapshotStrategy cameraStrategy = getCameraSpecificStrategy(cameraId);
        if (cameraStrategy != null) {
            log.debug("摄像头[{}]使用专属策略: {}", cameraId, cameraStrategy.getStrategyName());
            return cameraStrategy;
        }
        
        // 2. 使用全局默认策略
        HwCameraSnapshotStrategy globalStrategy = getGlobalDefaultStrategy();
        if (globalStrategy != null) {
            log.debug("摄像头[{}]使用全局默认策略: {}", cameraId, globalStrategy.getStrategyName());
            return globalStrategy;
        }
        
        log.warn("摄像头[{}]没有可用的抓图策略", cameraId);
        return null;
    }
    
    @Override
    public SnapshotConfig getCurrentSnapshotConfig(Long cameraId) {
        SnapshotConfig config = new SnapshotConfig();
        
        // 获取有效策略
        HwCameraSnapshotStrategy strategy = getEffectiveStrategy(cameraId);
        if (strategy == null) {
            config.setShouldSnapshot(false);
            config.setConfigSource("无可用策略");
            return config;
        }
        
        // 填充基础配置
        config.setStrategyId(strategy.getId());
        config.setStrategyName(strategy.getStrategyName());
        config.setConfigSource(strategy.getGlobalDefault() ? "全局默认策略" : "摄像头专属策略");
        
        // 判断是否应该抓图
        boolean shouldSnapshot = shouldSnapshotByStrategy(cameraId, strategy);
        config.setShouldSnapshot(shouldSnapshot);
        
        return config;
    }
    
    @Override
    public boolean shouldSnapshotNow(Long cameraId) {
        SnapshotConfig config = getCurrentSnapshotConfig(cameraId);
        return config.getShouldSnapshot() != null && config.getShouldSnapshot();
    }
    
    @Override
    public HwCameraSnapshotStrategy getGlobalDefaultStrategy() {
        return snapshotStrategyMapper.selectGlobalDefault();
    }
    
    @Override
    public boolean hasReachedInterval(Long cameraId, int intervalSeconds) {
        // 查询最近一次成功抓图记录
        HwCameraSnapshotRecord lastRecord = snapshotRecordMapper.selectLatestByCameraId(cameraId);
        
        if (lastRecord == null) {
            log.debug("摄像头[{}]没有抓图记录，可以抓图", cameraId);
            return true; // 没有抓图记录，可以抓图
        }
        
        LocalDateTime lastSnapshotTime = lastRecord.getCreateTime();
        LocalDateTime now = LocalDateTime.now();
        long secondsSinceLastSnapshot = Duration.between(lastSnapshotTime, now).getSeconds();
        
        boolean reached = secondsSinceLastSnapshot >= intervalSeconds;
        log.debug("摄像头[{}]距离上次抓图{}秒，间隔要求{}秒，{}",
            cameraId, secondsSinceLastSnapshot, intervalSeconds, reached ? "已达到" : "未达到");
        
        return reached;
    }
    
    // ==================== 私有辅助方法 ====================
    
    /**
     * 获取摄像头专属策略
     */
    private HwCameraSnapshotStrategy getCameraSpecificStrategy(Long cameraId) {
        // 获取有效的策略关联
        HwCameraSnapshotRelation relation = snapshotRelationMapper.selectEffectiveRelationByCameraId(cameraId);
        
        if (relation == null) {
            return null;
        }
        
        // 查询策略详情
        HwCameraSnapshotStrategy strategy = snapshotStrategyMapper.selectById(relation.getStrategyId());
        if (strategy != null && strategy.getStatus() && !strategy.getDeleted()) {
            return strategy;
        }
        
        return null;
    }
    
    /**
     * 根据策略判断是否应该抓图（定时任务调用）
     * 
     * 注意：此方法用于定时抓图场景
     * - 手动抓图：通过 manualSnapshot() API 直接触发
     * - 事件抓图：通过 eventSnapshot() API 直接触发
     * - 定时抓图：由此方法判断是否达到抓图间隔
     */
    private boolean shouldSnapshotByStrategy(Long cameraId, HwCameraSnapshotStrategy strategy) {
        // 1. 检查策略是否启用
        if (!strategy.getStatus()) {
            log.debug("策略[{}]已禁用", strategy.getStrategyName());
            return false;
        }
        
        // 2. 检查是否达到抓图间隔时间
        Integer intervalSeconds = strategy.getIntervalSeconds();
        if (intervalSeconds == null || intervalSeconds <= 0) {
            log.warn("策略[{}]的间隔时间配置无效: {}", strategy.getStrategyName(), intervalSeconds);
            return false;
        }
        
        // 3. 判断是否达到间隔时间
        boolean reached = hasReachedInterval(cameraId, intervalSeconds);
        log.debug("摄像头[{}]使用策略[{}]，抓图间隔{}秒，{}",
            cameraId, strategy.getStrategyName(), intervalSeconds, reached ? "可以抓图" : "未达到间隔");
        
        return reached;
    }
}



